/**
 * \file kernel/network/network.c
 * \author Davide Gessa
 * \date 12-09-2009
 */
#include <network/network.h>
#include <klibc/string.h>		
#include <klibc/stdio.h>	
#include <debug.h>			

/**
 * Inizializza il modulo di rete
 */
void network_init()
{
	DEBUGP("network_init()\n");
	
	network_ifaces = NULL;
	
	// Interfaccia di loopback
	network_iface_t *nt = (network_iface_t *) malloc(sizeof(network_iface_t));
	strcpy(nt->name, "lo\0");
	nt->type = NET_HARD_TYPE_LO;
	strcpy(nt->addr, (char [ADDR_LEN]) { 127,0,0,1 });
	strcpy(nt->mask, (char [ADDR_LEN]) { 255,0,0,0 });
	nt->if_gw = 0;
	nt->if_mac = 0;
	 
	network_iface_add(nt);
	network_iface_up("lo");
}



/**
 * Disabilita un interfaccia
 */
uint32_t network_iface_down(char *ifname)
{
	network_iface_t *ci;
	
	network_iface_get(ifname, &ci);
	
	if(ci != NULL)
	{
		ci->if_up = 0;
		
		return 0;
	}
	
	return 1;
}



/**
 * Abilita un interfaccia
 */
uint32_t network_iface_up(char *ifname)
{
	network_iface_t *ci;
	
	network_iface_get(ifname, &ci);
	
	if(ci != NULL)
	{
		ci->tx_bytes = 0;
		ci->rx_bytes = 0;
		ci->if_up = 1;
		
		return 0;
	}
	
	return 1;
}

/**
 * Aggiunge un interfaccia
 */
uint32_t network_iface_add(network_iface_t *iface)
{
	if(iface != NULL)
	{
		iface->next = network_ifaces;
		iface->if_up = 0;
		network_ifaces = iface;
		
		return 0;		
	}
	
	return 1;	
}




/**
 * Restituisce il fs numero x
 * 
 * \return stato operazione
 */
uint32_t network_iface_iget(uint32_t x, network_iface_t **iface)
{
	network_iface_t *cf = network_ifaces;
	uint32_t i = 0;
	*iface = NULL;
	
	while(cf != NULL)
	{
		if(i == x)
		{
			*iface = cf;
			return 0;
		}
		i++;
		cf = cf->next;
	}
	return 1;	
}



/**
 * Restituisce l'interfaccia dato il nome
 * 
 * \return stato operazione
 */
uint32_t network_iface_get(char *name, network_iface_t **iface)
{
	network_iface_t *cf = network_ifaces;
	*iface = NULL;
	
	while(cf != NULL)
	{
		if(strcmp(name, cf->name) == 0)
		{
			*iface = cf;
			return 0;
		}
		
		cf = cf->next;
	}
	return 1;
}



/**
 * Trasforma un indirizzo in una stringa
 */
char *network_addrtoa(char *addr, char *str)
{
	strcpy(str, itoa((uint8_t) addr[0]));
	strcat(str, ".");
	strcat(str, itoa((uint8_t) addr[1]));
	strcat(str, ".");
	strcat(str, itoa((uint8_t) addr[2]));
	strcat(str, ".");
	strcat(str, itoa((uint8_t) addr[3]));
	strcat(str, "\0");
	
	return str;
}
